/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package commons.util;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.List;

/**
 * Class description
 *
 *
 * @version        Enter version here..., 12/10/09
 * @author         Susanta Tewari
 */
public class Util {

    public static final String IMAGE_FORMAT_JPEG = "jpeg";
    public static final String IMAGE_FORMAT_PNG  = "png";

    /**
     * Constructs ...
     *
     */
    private Util() {}

    /**
     * Method description
     *
     *
     * @param file
     * @param format
     * @param comp
     * @param width
     * @param height
     */
    public static void saveImage(File file, String format, JComponent comp, int width, int height) {

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        Graphics2D g2       = image.createGraphics();

        comp.paint(g2);
        g2.dispose();

        try {
            ImageIO.write(image, format, file);
        } catch (IOException ioe) {
            System.err.println(ioe.getMessage());
        }
    }

    /**
     * Method description
     *
     *
     * @param oldOrder
     *
     * @return
     */
    public static int[] randomBlockReversal(int[] oldOrder) {

        int[] newOrder = oldOrder.clone();


        // choose 2 end points (i and j) randomly on the length of the order
        int i = (int) (Math.random() * newOrder.length);
        int j = (int) (Math.random() * newOrder.length);

        i = Math.min(i, j);
        j = Math.max(i, j);


        // reverse the block between i and j, including i and j.
        for (int k = i; k <= j; k++) {
            newOrder[k] = oldOrder[j - k + i];
        }

        return newOrder;
    }

    /**
     * Method description
     *
     *
     * @param array
     *
     * @return
     */
    public static int findMax(int[] array) {

        int max = array[0];

        for (int i = 1; i < array.length; i++) {

            if (array[i] > max) {
                max = array[i];
            }
        }

        return max;
    }

    /**
     * Method description
     *
     *
     * @param array
     *
     * @return
     */
    public static int findMin(int[] array) {

        int min = array[0];

        for (int i = 1; i < array.length; i++) {

            if (array[i] < min) {
                min = array[i];
            }
        }

        return min;
    }

    /**
     * Method description
     *
     *
     * @param comp
     */
    public static void showFrame(Component comp) {

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
                 | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        JFrame frame = new JFrame();
        JPanel panel = new JPanel();

        panel.add(comp);
        frame.setLocation(100, 100);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static List<Integer> createSeq(int n, boolean startAtZero) {

        List<Integer> seq = new ArrayList<>(n);
        int counter       = 1;

        if (startAtZero) counter = 0;

        for (int i = 0; i < n; i++) {

            seq.add(counter);

            counter++;
        }

        return seq;
    }

    /**
     * Method description
     *
     *
     * @param labelCount
     * @param labelPrefix
     *
     * @return
     */
    public static Collection<String> createLabels(int labelCount, String labelPrefix) {

        Collection<String> result = new ArrayList<>();

        for (int i = 1; i <= labelCount; i++) {
            result.add(labelPrefix + i);
        }

        return result;
    }

    /**
     * Method description
     *
     *
     * @param keys
     * @param values
     * @param <K>
     * @param <V>
     *
     * @return
     */
    public static <K, V> Map<K, V> createMap(K[] keys, V[] values) {

        if (keys.length != values.length) {
            throw new IllegalArgumentException("keys  and values count do not match");
        }

        Map<K, V> result = new HashMap<>();

        for (int i = 0; i < keys.length; i++) {
            result.put(keys[i], values[i]);
        }

        return result;
    }

    /**
     * Class description
     *
     *
     * @version        Enter version here..., 12/10/09
     * @author         Susanta Tewari
     */
    public static class IO {

        /**
         * Constructs ...
         *
         */
        private IO() {}

        /**
         * Method description
         *
         *
         * @param file
         * @param str
         *
         * @throws IOException
         */
        public static void writeToFile(File file, String str) throws IOException {

            PrintWriter outFile = null;

            outFile = new PrintWriter(new BufferedWriter(new FileWriter(file, false)));

            outFile.print(str);
            outFile.close();
        }

        /**
         * Method description
         *
         *
         * @param file
         * @param str
         *
         * @throws IOException
         */
        public static void writeToFileAppend(File file, String str) throws IOException {

            PrintWriter outFile = null;

            outFile = new PrintWriter(new BufferedWriter(new FileWriter(file, true)));

            outFile.print(str);
            outFile.close();
        }

        /**
         * Reads the lines of the specified text file. Note that this method does not block
         * non-textual files as input. See {@link java.nio.file.Files#probeContentType(java.nio.file.Path)}.
         *
         * @param file any text file but does not block non-textual files as input
         * @return list of lines in the specified text file
         * @throws FileNotFoundException if the file does not exist, is a directory rather than a
         * regular file, or for some other reason cannot be opened for reading.
         * @throws IOException If an I/O error occurs
         */
        public static List<String> readLines(File file) throws FileNotFoundException, IOException {

            List<String> lines = new ArrayList<>(30);

            try (BufferedReader reader = new BufferedReader(new FileReader(file))) {

                String line = reader.readLine();

                while (line != null) {

                    lines.add(line);

                    line = reader.readLine();
                }
            }

            return lines;
        }
    }
}
